DTOcean Tidal Hydrodynamics Example

Note, this example assumes the Hydroynamics Module has been installed


In [ ]:
%matplotlib inline

In [ ]:
from IPython.display import display, HTML

In [ ]:
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (14.0, 8.0)

In [ ]:
import numpy as np

In [ ]:
from dtocean_core import start_logging
from dtocean_core.core import Core
from dtocean_core.menu import DataMenu, ModuleMenu, ProjectMenu
from dtocean_core.pipeline import Tree

In [ ]:
def html_list(x):
    message = "<ul>"
    for name in x:
        message += "<li>{}</li>".format(name)
    message += "</ul>"
    return message
def html_dict(x):
    message = "<ul>"
    for name, status in x.iteritems():
        message += "<li>{}: <b>{}</b></li>".format(name, status)
    message += "</ul>"
    return message

In [ ]:
# Bring up the logger
start_logging()

Create the core, menus and pipeline tree

The core object carrys all the system information and is operated on by the other classes


In [ ]:
new_core = Core()
data_menu = DataMenu()
project_menu = ProjectMenu()
module_menu = ModuleMenu()
pipe_tree = Tree()

Create a new project


In [ ]:
project_title = "DTOcean"  
new_project = project_menu.new_project(new_core, project_title)

Set the device type


In [ ]:
options_branch = pipe_tree.get_branch(new_core, new_project, "System Type Selection")
variable_id = "device.system_type"
my_var = options_branch.get_input_variable(new_core, new_project, variable_id)
my_var.set_raw_interface(new_core, "Tidal Fixed")
my_var.read(new_core, new_project)

Initiate the pipeline

This step will be important when the database is incorporated into the system as it will effect the operation of the pipeline.


In [ ]:
project_menu.initiate_pipeline(new_core, new_project)

Discover available modules


In [ ]:
names = module_menu.get_available(new_core, new_project)
message = html_list(names)
HTML(message)

Activate a module

Note that the order of activation is important and that we can't deactivate yet!


In [ ]:
module_name = 'Hydrodynamics'
module_menu.activate(new_core, new_project, module_name)
hydro_branch = pipe_tree.get_branch(new_core, new_project, 'Hydrodynamics')

Check the status of the module inputs


In [ ]:
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Initiate the dataflow

This indicates that the filtering and module / theme selections are complete


In [ ]:
project_menu.initiate_dataflow(new_core, new_project)

Move the system to the post-filter state and ready the system


In [ ]:
new_core.inspect_level(new_project, "modules initial")
new_core.reset_level(new_project, preserve_level=True)

Load test data

Prepare the test data for loading. The files required can be found in the test_data directory of the source code and should be copied to the directory that the notebook is running. When the python file is run a pickle file is generated containing a dictionary of inputs.


In [ ]:
%run test_data/inputs_wp2_tidal.py

In [ ]:
hydro_branch.read_test_data(new_core,
                            new_project,
                            "test_data/inputs_wp2_tidal.pkl")

Get a variable from the tree


In [ ]:
variable_id = 'project.rated_power'
my_var = hydro_branch.get_input_variable(new_core, new_project, variable_id)

Discover which interfaces can be used to enter the variable

Each piece of data must be provided by one or many interfaces, be that raw input or from special file types.


In [ ]:
list_raw = my_var.get_raw_interfaces(new_core)
message = html_list(list_raw)
HTML(message)

Check that the variable has been entered correctly


In [ ]:
variable_value = new_core.get_data_value(new_project, variable_id)
display(variable_value)

Auto plot a variable


In [ ]:
new_var = hydro_branch.get_input_variable(new_core,
                                          new_project,
                                          'device.turbine_performance')

In [ ]:
new_var.plot(new_core, new_project)

Look for other available plots


In [ ]:
plots = new_var.get_available_plots(new_core, new_project)
msg = html_list(plots)
HTML(msg)

Plot a specific plot


In [ ]:
new_var.plot(new_core, new_project, 'Tidal Power Performance')

Check if the module can be executed


In [ ]:
can_execute = module_menu.is_executable(new_core, new_project, module_name)
display(can_execute)

In [ ]:
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Execute the current module

The "current" module refers to the next module to be executed in the chain (pipeline) of modules. This command will only execute that module and another will be used for executing all of the modules at once.

Note, any data supplied by the module will be automatically copied into the active data state.


In [ ]:
module_menu.execute_current(new_core, new_project)

Examine the results

Currently, there is no robustness built into the core, so the assumption is that the module executed successfully. This will have to be improved towards deployment of the final software.

Let's check the number of devices and annual output of the farm, using just information in the data object.


In [ ]:
n_devices = new_core.get_data_value(new_project, "project.number_of_devices")
meta = new_core.get_metadata("project.number_of_devices")
name = meta.title
message_one = "<p><b>{}:</b> {}</p>".format(name, n_devices)

farm_annual_energy = new_core.get_data_value(new_project, "project.annual_energy")
meta = new_core.get_metadata("project.annual_energy")
name = meta.title
value = farm_annual_energy
units = meta.units[0]
message_two = "<p><b>{}:</b> <i>{}</i> ({})</p>".format(name, value, units)

HTML(message_one + message_two)

Plotting some graphs

By having data objects with set formats it should be possible to create automated plot generation. However, some plots may be too complex and some special cases may need defined.


In [ ]:
mean_power_per_dev_value = new_core.get_data_value(new_project, 
                                                      "project.mean_power_per_device")
meta = new_core.get_metadata("project.mean_power_per_device")

chart_values = np.array(mean_power_per_dev_value.values())

In [ ]:
plt.bar(range(len(mean_power_per_dev_value)),
        chart_values,
        align='center')
            
plt.xticks(range(len(mean_power_per_dev_value)),
          mean_power_per_dev_value.keys())
plt.title(meta.title)

plt.ylabel(meta.units[0])

plt.tight_layout()
# plt.savefig('annual_power_per_device.png')
plt.show()

Plotting the Layout

This may require such a special case. It is not clear is a new data type is required or just special plots associated to variable IDs.


In [ ]:
layout_value = new_core.get_data_value(new_project, "project.layout")
layout_meta = new_core.get_metadata("project.layout")

In [ ]:
x = []
y = []

for coords in layout_value.itervalues():
    
    x.append(coords.x)
    y.append(coords.y)

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1, axisbg='lightskyblue')
ax1.plot(x,y,'k+', mew=2, markersize=10)
plt.title(layout_meta.title)
plt.axis('equal')
plt.show()

In [ ]:
pmf_values = new_core.get_data_value(new_project, "project.mean_power_pmf_per_device")
display(pmf_values)

In [ ]:
plt.plot(pmf_values["device001"][:,0], pmf_values["device001"][:,1], '+', mew=5, markersize=20)
plt.tight_layout()
plt.show()

In [ ]:
tidal_occurance = new_core.get_data_value(new_project, "farm.tidal_occurrence")

In [ ]:
print tidal_occurance.p.values

In [ ]:
plt.quiver(tidal_occurance["U"].values[:,:,1],
           tidal_occurance["V"].values[:,:,1])
plt.show()

In [ ]:
hist_values = new_core.get_data_value(new_project, "project.mean_power_hist_per_device")

In [ ]:
plot_bins = hist_values["device001"]['bins']
plot_values = hist_values["device001"]['values']

_ = plt.bar(plot_bins[:-1], plot_values, width=plot_bins[1:] - plot_bins[:-1])
plt.show()

In [ ]: